package com.lemon.boot.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.NumberUtil;
import com.lemon.boot.common.base.BaseServiceImpl;
import com.lemon.boot.common.consts.ApiConst;
import com.lemon.boot.common.entity.LoginUserDetail;
import com.lemon.boot.common.enums.DeleteEnum;
import com.lemon.boot.common.enums.StatusEnum;
import com.lemon.boot.common.listener.ApplicationStartEventListener;
import com.lemon.boot.common.utils.JwtUtil;
import com.lemon.boot.dao.TenantMenuDAO;
import com.lemon.boot.dto.TenantMenuDTO;
import com.lemon.boot.dto.TenantMenuResourceDTO;
import com.lemon.boot.po.*;
import com.lemon.boot.service.*;
import com.lemon.boot.vo.LeftMenuVO;
import com.lemon.boot.vo.TenantMenuResourceVO;
import com.lemon.boot.vo.TreeSelectVO;
import com.lemon.boot.vo.TreeTenantMenuVO;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * 租户-菜单中间表 业务实现类
 *
 * @author Lemon
 * @since 2024-02-29
 */
@Log4j2
@Service
public class TenantMenuServiceImpl extends BaseServiceImpl<TenantMenuDAO, TenantMenuPO, TenantMenuDTO> implements ITenantMenuService {
    @Resource
    private IRoleMenuService iRoleMenuService;
    @Resource
    private IResourceService iResourceService;
    @Resource
    private IMenuResourceService iMenuResourceService;
    @Resource
    @Lazy
    private IMenuService iMenuService;
    @Resource
    private ApplicationStartEventListener applicationStartEventListener;

    @Override
    @Transactional
    public String add(TenantMenuPO tenantMenuPO) {
        //1.当前用户信息
        LoginUserDetail currentUser = JwtUtil.getCurrentUser();

        //2.判断用户是否存在
        Dict dict = this.exists(tenantMenuPO, currentUser);
        if (dict.getBool("success")) {
            return dict.getStr("msg");
        }

        //3.设置默认值
        tenantMenuPO.setTenantId(currentUser.getTenantId());

        //4.执行添加
        String result = super.add(tenantMenuPO);

        //5.修改 tree_link_id,seq
        this.update().set("tree_link_id", getTreeLinkId(tenantMenuPO)).set("seq", getSeq(currentUser.getTenantId())).eq("id", tenantMenuPO.getId()).update();

        return result;
    }

    @Override
    @Transactional
    public String del(Long id) {
        //1.获取所有的子功能菜单
        List<TenantMenuPO> childList = this.baseMapper.getIdByTreeLinkId(id);
        if (!CollectionUtils.isEmpty(childList)) {
            //2.重新设置子功能菜单的树形结构
            List<TenantMenuPO> childFunctionalMenuList = childList.stream()
                    .filter(item -> Objects.nonNull(item.getMenuId()))
                    .peek(item -> item.setParentId(ApiConst.SUPER_PARENT_ID)
                            .setTreeLinkId(String.format("%s,%s", ApiConst.SUPER_PARENT_ID, item)))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(childFunctionalMenuList)) {
                this.updateBatchById(childFunctionalMenuList);
            }

            //3.删除子菜单不包括功能菜单
            List<Long> childCommonMenuIdList = childList.stream().map(TenantMenuPO::getMenuId).filter(Objects::isNull).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(childCommonMenuIdList)) {
                this.removeByIds(childFunctionalMenuList);
            }
        }

        return "删除成功！";
    }

    @Override
    @Transactional
    public String edit(TenantMenuPO tenantMenuPO) {
        //1.当前用户信息
        LoginUserDetail currentUser = JwtUtil.getCurrentUser();

        //2.判断用户是否存在
        Dict dict = this.exists(tenantMenuPO, currentUser);
        if (dict.getBool("success")) {
            return dict.getStr("msg");
        }

        //3.不能修改同级部门
        if (tenantMenuPO.getId().equals(tenantMenuPO.getParentId())) {
            return "同一菜单不能为父子关系";
        }

        //4.验证父子部门关系
        if (!ApiConst.SUPER_PARENT_ID.equals(tenantMenuPO.getParentId())) {
            TenantMenuPO parentMenu = this.query().select("tree_link_id").eq("id", tenantMenuPO.getParentId()).last("limit 1").one();
            List<Long> parentIdList = Arrays.stream(parentMenu.getTreeLinkId().split(",")).map(NumberUtil::parseLong).collect(Collectors.toList());
            if (parentIdList.contains(tenantMenuPO.getId())) {
                return "父子菜单错误";
            }
        }

        //6.保存之前的 tree_link_id
        if (!StringUtils.hasText(tenantMenuPO.getTreeLinkId())) {
            TenantMenuPO menu = this.query().select("tree_link_id").eq("id", tenantMenuPO.getId()).last("limit 1").one();
            if (menu != null && StringUtils.hasText(menu.getTreeLinkId())) {
                tenantMenuPO.setTreeLinkId(menu.getTreeLinkId());
            }
        }
        String oldTreeLinkId = tenantMenuPO.getTreeLinkId();

        //7.设置新的 tree_link_id
        String newTreeLinkId = getTreeLinkId(tenantMenuPO);

        //8.根据 tree_link_id 获取数据
        List<TenantMenuPO> menuList = this.query().select("id", "tree_link_id").likeRight("tree_link_id", oldTreeLinkId).list();
        if (!CollectionUtils.isEmpty(menuList)) {
            menuList.forEach(item -> {
                item.setTreeLinkId(item.getTreeLinkId().replace(oldTreeLinkId, newTreeLinkId));
                item.setUpdateBy(currentUser.getName());
            });
            this.updateBatchById(menuList);
        }

        return super.edit(tenantMenuPO);
    }

    /**
     * 判断部门名称是否重复
     *
     * @param tenantMenuPO
     * @param currentUser
     * @return
     */
    private Dict exists(TenantMenuPO tenantMenuPO, LoginUserDetail currentUser) {
        //1.判断是否存在
        boolean exists = this.query().select("1").eq("name", tenantMenuPO.getName()).eq("tenant_id", currentUser.getTenantId()).ne(tenantMenuPO.getId() != null, "id", tenantMenuPO.getId()).isNull("menu_id").last("limit 1").exists();

        //2.封装返回结果
        return Dict.create().set("success", exists).set("msg", String.format("菜单名称\"%s\"已存在！", tenantMenuPO.getName()));
    }

    /**
     * 根据ID获取 tree_link_id
     *
     * @param tenantMenuPO
     * @return
     */
    private String getTreeLinkId(TenantMenuPO tenantMenuPO) {
        //1.获取 tree_link_id
        if (!StringUtils.hasText(tenantMenuPO.getTreeLinkId())) {
            TenantMenuPO menu = this.query().select("tree_link_id").eq("id", tenantMenuPO.getId()).last("limit 1").one();
            if (menu != null && StringUtils.hasText(menu.getTreeLinkId())) {
                tenantMenuPO.setTreeLinkId(menu.getTreeLinkId());
            }
        }

        //2.设置 tree_link_id 字段
        if (ApiConst.SUPER_PARENT_ID.equals(tenantMenuPO.getParentId())) {
            tenantMenuPO.setTreeLinkId(String.format("%s,%s", ApiConst.SUPER_PARENT_ID, tenantMenuPO.getId()));
        } else {
            TenantMenuPO parentMenu = this.query().select("tree_link_id").eq("id", tenantMenuPO.getParentId()).last("limit 1").one();
            tenantMenuPO.setTreeLinkId(String.format("%s,%s", parentMenu.getTreeLinkId(), tenantMenuPO.getId()));
        }
        return tenantMenuPO.getTreeLinkId();
    }

    /**
     * 获取排序字段
     *
     * @param tenantId
     * @return
     */
    private int getSeq(Long tenantId) {
        //1.获取排序字段的最大值
        TenantMenuPO maxSeq = this.query().select("max(seq) seq").eq("tenant_id", tenantId).eq(StatusEnum.ENABLE.getColumn(), StatusEnum.ENABLE.getStatus()).one();

        if (Objects.isNull(maxSeq) || maxSeq.getSeq() == null) {
            return 0;
        }
        return maxSeq.getSeq() + 1;
    }

    @Override
    @Transactional
    public String addOrEdit(TenantMenuPO tenantMenuPO) {
        return tenantMenuPO.getId() == null ? this.add(tenantMenuPO) : this.edit(tenantMenuPO);
    }

    @Override
    public List<LeftMenuVO> getLeftMenu() {
        //1.当前登录的用户信息
        LoginUserDetail currentUser = JwtUtil.getCurrentUser();

        //2.查询菜单信息
        Map<String, Object> param = ApiConst.enableStatusAndUnableDelete();
        param.put("userId", currentUser.getUserId());
        param.put("tenantId", currentUser.getTenantId());
        List<LeftMenuVO> leftMenuList = this.baseMapper.getLeftMenu(param);
        if (CollectionUtils.isEmpty(leftMenuList)) {
            return leftMenuList;
        }

        //3.给菜单集合设置路由设置路由
        leftMenuList.stream().filter(item -> StringUtils.hasText(item.getPath())).forEach(item -> {
            String path = item.getPath().toLowerCase(Locale.ENGLISH);
            item.setPath(path.endsWith(".vue") ? path.substring(0, path.length() - 4) : path);
        });

        //4.设置 tree_link_id
        Map<Long, String> menuIdNameMap = leftMenuList.stream().collect(Collectors.toMap(LeftMenuVO::getId, LeftMenuVO::getName));
        leftMenuList.stream().filter(item -> StringUtils.hasText(item.getTreeLinkId())).forEach(item -> {
            String[] idArr = item.getTreeLinkId().split(",");
            String[] nameArr = new String[idArr.length - 1];
            for (int i = 0; i < nameArr.length; i++) {
                nameArr[i] = menuIdNameMap.get(NumberUtil.parseLong(idArr[i + 1]));
            }
            item.setBread(nameArr);
        });

        //5.根据 parentId 分组
        Map<Long, List<LeftMenuVO>> listMap = leftMenuList.stream().collect(groupingBy(LeftMenuVO::getParentId));

        //6.给父菜单设置子菜单
        List<LeftMenuVO> childMenuList = new ArrayList<>();
        leftMenuList.forEach(item -> {
            List<LeftMenuVO> menuList = listMap.get(item.getId());
            item.setChildren(menuList);
            if (!CollectionUtils.isEmpty(menuList)) {
                childMenuList.addAll(menuList);
            }
        });

        //7.父菜单
        return leftMenuList.stream().filter(item -> !childMenuList.contains(item)).filter(item -> item.getParentId().equals(ApiConst.SUPER_PARENT_ID)).collect(Collectors.toList());
    }

    @Override
    public List<TreeTenantMenuVO> list(TenantMenuDTO tenantMenuDTO) {
        //1.当前用户
        LoginUserDetail currentUser = JwtUtil.getCurrentUser();

        //2.设置参数
        tenantMenuDTO.setTenantId(currentUser.getTenantId());
        tenantMenuDTO.setTenantMenuIdList(CollectionUtil.newArrayList(ApiConst.SUPER_PARENT_ID));
        //tenantMenuDTO.setStatus(StatusEnum.ENABLE.getStatus());
        tenantMenuDTO.setDeleted(DeleteEnum.UNABLE.getDeleted());

        //3.搜索
        if (StringUtils.hasText(tenantMenuDTO.getName()) || tenantMenuDTO.getStatus() != null) {
            //3.1.根据状态和名称查询部门ID
            List<Long> idList = this.baseMapper.getParentIdByStatusAndName(tenantMenuDTO);
            if (CollectionUtils.isEmpty(idList)) {
                return null;
            }
            tenantMenuDTO.setTenantMenuIdList(idList);
        }

        //4.查询数据
        List<TreeTenantMenuVO> treeTenantMenuList = this.baseMapper.getByMenuIdAndTenantId(tenantMenuDTO);
        if (CollectionUtils.isEmpty(treeTenantMenuList)) {
            return null;
        }

        //5.根据parent_id分组
        Map<Long, List<TreeTenantMenuVO>> listMap = treeTenantMenuList.stream().collect(groupingBy(TreeTenantMenuVO::getParentId));

        //6.设置子菜单
        List<Long> childIdList = new ArrayList<>();
        treeTenantMenuList.forEach(item -> {
            List<TreeTenantMenuVO> childList = listMap.get(item.getId());
            if (!CollectionUtils.isEmpty(childList)) {
                childList.get(0).setFirst(true);
                childList.get(childList.size() - 1).setLast(true);
                item.setChildren(childList);
                childIdList.addAll(childList.stream().map(TreeTenantMenuVO::getId).collect(Collectors.toList()));
            }
        });

        //7.获取所有父菜单的数据（因为子菜单以及在父菜单中）
        List<TreeTenantMenuVO> result = treeTenantMenuList.stream().filter(item -> tenantMenuDTO.getTenantMenuIdList().contains(item.getParentId()) && !childIdList.contains(item.getId())).collect(Collectors.toList());
        result.get(0).setFirst(true);
        result.get(result.size() - 1).setLast(true);
        return result;
    }

    @Override
    @Transactional
    public void order(Map<String, Object> param) {
        //1.获取id
        Long id = NumberUtil.parseLong(param.get("id").toString());

        //2.获取 isUp
        boolean isUp = Boolean.parseBoolean(param.get("isUp").toString());

        //3.根据ID查询数据
        List<TenantMenuPO> list = this.baseMapper.getSeqById(id);

        //4.判断是否是向上移动
        if (isUp) {
            for (int i = 0; i < list.size(); i++) {
                TenantMenuPO po = list.get(i);
                if (id.equals(po.getId())) {
                    TenantMenuPO menuPO = list.get(i - 1);
                    menuPO.setSeq(i);
                    po.setSeq(i - 1);
                } else {
                    po.setSeq(i);
                }
            }
        } else {
            for (int i = 0; i < list.size(); i++) {
                TenantMenuPO po = list.get(i);
                if (id.equals(po.getId())) {
                    TenantMenuPO menuPO = list.get(i + 1);
                    menuPO.setSeq(i);
                    po.setSeq(i + 1);
                    i++;
                } else {
                    po.setSeq(i);
                }
            }
        }
        //批量修改
        this.baseMapper.updateSeqById(list);
    }

    @Override
    public List<TenantMenuResourceVO> getByRoleIdTenantId(Long roleId, Long tenantId) {
        //1.获取所有的资源路径
        Map<String, List<String>> allPath = applicationStartEventListener.getNotSecurityPathToMap();

        //2.请求参数
        Map<String, Object> param = ApiConst.enableStatusAndUnableDelete();
        param.put("tenantId", tenantId);

        //3.查询数据
        List<TenantMenuResourceVO> treeTenantMenuList = this.baseMapper.getByTenantId(param);
        if (CollectionUtils.isEmpty(treeTenantMenuList)) {
            return new ArrayList<>(0);
        } else {
            treeTenantMenuList = treeTenantMenuList.stream()
                    .filter(item -> item.getMenuId() == null || (StringUtils.hasText(item.getPath()) && allPath.containsKey(item.getPath().startsWith("/") ? item.getPath() : ("/" + item.getPath()))))
                    .collect(Collectors.toList());
        }

        //4.根据角色ID查询sys_role_menu是否包含菜单ID
        List<RoleMenuPO> roleMenuList = iRoleMenuService.listByMap(Collections.singletonMap("role_id", roleId));
        if (!CollectionUtils.isEmpty(roleMenuList)) {
            //4.1.获取租户菜单的ID，用来判断选择
            List<Long> tenantMenuIdList = roleMenuList.stream().map(RoleMenuPO::getTenantMenuId).distinct().collect(Collectors.toList());
            treeTenantMenuList.forEach(item -> item.setSelected(tenantMenuIdList.contains(item.getId())));
        }

        //5.查询所有的资源
        List<ResourcePO> resourceList = iResourceService.query()
                .select("id", "name", "path")
                .eq(StatusEnum.ENABLE.getColumn(), StatusEnum.ENABLE.getStatus())
                .eq(DeleteEnum.UNABLE.getColumn(), DeleteEnum.UNABLE.getDeleted())
                .list();

        //6.设置所有的资源集合、已存在的资源
        if (!CollectionUtils.isEmpty(resourceList)) {
            //6.1.查询已存在的资源
            List<MenuResourcePO> menuResourceList = iMenuResourceService.query().select("tenant_menu_id", "resource_id").eq("role_id", roleId).list();

            treeTenantMenuList.stream().filter(item -> item.getMenuId() != null).forEach(item -> {
                //6.2.设置所有的资源-要在系统接口的范围内
                Map<Long, String> allResourceMap = resourceList.stream().filter(resource -> allPath.get(item.getPath()).contains(resource.getPath().startsWith("/") ? resource.getPath() : ("/" + resource.getPath()))).collect(Collectors.toMap(ResourcePO::getId, ResourcePO::getName));
                item.setAllResourceList(allResourceMap);

                //6.3.获取当前菜单的资源ID
                List<Long> selectResourceIdList = menuResourceList.stream().filter(source -> source.getTenantMenuId().equals(item.getId())).map(MenuResourcePO::getResourceId).collect(Collectors.toList());

                //6.4.设置选择的资源
                item.setSelectResourceList(selectResourceIdList);
            });
        }

        //7.根据parent_id分组
        Map<Long, List<TenantMenuResourceVO>> listMap = treeTenantMenuList.stream().collect(groupingBy(TenantMenuResourceVO::getParentId));

        //8.设置子菜单
        treeTenantMenuList.forEach(item -> item.setChildren(listMap.get(item.getId())));

        //9.获取所有父菜单的数据（因为子菜单以及在父菜单中）
        return treeTenantMenuList.stream().filter(item -> item.getParentId().equals(ApiConst.SUPER_PARENT_ID)).collect(Collectors.toList());
    }

    @Override
    public List<TenantMenuResourceVO> getAllMenuResourceByCurrent() {
        //1.请求参数
        Map<String, Object> param = ApiConst.enableStatusAndUnableDelete();
        param.put("tenantId", JwtUtil.getCurrentUser().getTenantId());

        //2.查询数据
        List<TenantMenuResourceVO> treeTenantMenuList = this.baseMapper.getByTenantId(param);
        if (CollectionUtils.isEmpty(treeTenantMenuList)) {
            return new ArrayList<>(0);
        }

        //3.查询所有的资源
        Map<Long, String> resourceList = iResourceService.query().select("id", "name").eq(StatusEnum.ENABLE.getColumn(), StatusEnum.ENABLE.getStatus()).list().stream().collect(Collectors.toMap(ResourcePO::getId, ResourcePO::getName));

        //4.设置所有的资源集合
        if (!CollectionUtils.isEmpty(resourceList)) {
            treeTenantMenuList.stream().filter(item -> item.getMenuId() != null).forEach(item -> item.setAllResourceList(resourceList));
        }

        //5.根据parent_id分组
        Map<Long, List<TenantMenuResourceVO>> listMap = treeTenantMenuList.stream().collect(groupingBy(TenantMenuResourceVO::getParentId));

        //6.设置子菜单
        treeTenantMenuList.forEach(item -> item.setChildren(listMap.get(item.getId())));

        //7.获取所有父菜单的数据（因为子菜单以及在父菜单中）
        return treeTenantMenuList.stream().filter(item -> item.getParentId().equals(ApiConst.SUPER_PARENT_ID)).collect(Collectors.toList());
    }

    @Override
    public TenantMenuPO get(Long id) {
        TenantMenuPO result = super.get(id);

        //1.设置菜单名称
        if (!StringUtils.hasText(result.getName()) && result.getMenuId() != null) {
            MenuPO menuPO = iMenuService.query().select("name").eq("id", result.getMenuId()).last("limit 1").one();
            result.setName(menuPO.getName());
        }
        return result;
    }

    @Override
    public List<TreeSelectVO> getParentByTreeSelect() {
        //1.当前用户
        LoginUserDetail currentUser = JwtUtil.getCurrentUser();

        //2.设置参数
        Map<String, Object> param = ApiConst.enableStatusAndUnableDelete();
        param.put("tenantId", currentUser.getTenantId());

        //3.查询数据
        List<TreeSelectVO> treeDeptList = this.baseMapper.getByTreeSelect(param);
        if (CollectionUtils.isEmpty(treeDeptList)) {
            return Collections.singletonList(new TreeSelectVO().setLabel(ApiConst.SUPER_MENU_NAME).setValue(ApiConst.SUPER_PARENT_ID));
        }

        //4.根据parent_id分组
        Map<Long, List<TreeSelectVO>> listMap = treeDeptList.stream().collect(groupingBy(TreeSelectVO::getParentId));

        //5.设置子菜单
        treeDeptList.forEach(item -> item.setChildren(listMap.get(item.getValue())));

        //6.获取所有父菜单的数据（因为子菜单以及在父菜单中）
        List<TreeSelectVO> result = treeDeptList.stream().filter(item -> ApiConst.SUPER_PARENT_ID.equals(item.getParentId())).collect(Collectors.toList());

        //7.创建值为-1的顶级部门
        return Collections.singletonList(new TreeSelectVO().setLabel(ApiConst.SUPER_MENU_NAME).setValue(ApiConst.SUPER_PARENT_ID).setChildren(result));
    }

    @Override
    @Transactional
    public String addMenuResourceByTenantId(TenantMenuResourceDTO tenantMenuResourceDTO) {
        //1.租户ID
        Long tenantId = tenantMenuResourceDTO.getTenantId();

        //2.查询租户已有的菜单
        List<TenantMenuPO> hasMenuList = this.query().select("id", "menu_id").eq("tenant_id", tenantId).list();

        //3.租户已有的菜单ID
        List<Long> hasMenuIdList = hasMenuList.stream().map(TenantMenuPO::getMenuId).filter(Objects::nonNull).distinct().collect(Collectors.toList());

        //4.传入的菜单ID集合
        List<Long> newMenuIdList = tenantMenuResourceDTO.getTenantMenuResourceList().stream().filter(TenantMenuResourceVO::isSelected).map(TenantMenuResourceVO::getMenuId).collect(Collectors.toList());

        //5.要删除的菜单ID集合,要添加的菜单ID集合
        List<Long> delMenuIdList = null, addMenuIdList = null;

        //6.设置要删除的菜单ID集合，要添加的菜单ID集合
        if (CollectionUtils.isEmpty(newMenuIdList)) {
            //6.1.如果传入的菜单ID为空，就删除已存在的菜单ID集合，添加为null
            delMenuIdList = hasMenuIdList;
        } else {
            //6.2.判断已存在的菜单ID集合
            if (CollectionUtils.isEmpty(hasMenuIdList)) {
                //6.3.如果没有已存在的菜单ID，传入的菜单ID就是要添加的
                addMenuIdList = newMenuIdList;
            } else {
                /**
                 * 6.4.传入的菜单ID有值，已存在的也有值
                 * 比如传入的是 234，已存在的是 345，那么添加的是2，要删除的是5
                 */
                addMenuIdList = newMenuIdList.stream().filter(item -> !hasMenuIdList.contains(item)).distinct().collect(Collectors.toList());
                delMenuIdList = hasMenuIdList.stream().filter(item -> !newMenuIdList.contains(item)).distinct().collect(Collectors.toList());
            }
        }

        //7.判断是否有要删除的
        if (!CollectionUtils.isEmpty(delMenuIdList)) {
            //7.1.根据菜单ID，租户ID，查询租户菜单
            List<TenantMenuPO> tenantMenuList = this.query().select("id").eq("tenant_id", tenantId).in("menu_id", delMenuIdList).list();
            if (!CollectionUtils.isEmpty(tenantMenuList)) {
                //7.2.获取租户菜单ID,角色ID,并删除 sys_role_menu
                List<Long> tenantMenuIdList = tenantMenuList.stream().map(TenantMenuPO::getId).distinct().collect(Collectors.toList());
                iRoleMenuService.update().in("tenant_menu_id", tenantMenuIdList).remove();
            }

            //7.3.根据菜单ID删除 sys_tenant_menu
            this.update().eq("tenant_id", tenantId).in("menu_id", delMenuIdList).remove();
        }

        //8.判断是否有要添加的
        if (!CollectionUtils.isEmpty(addMenuIdList)) {
            //8.1.添加sys_tenant_menu
            this.addByMenuIdList(tenantId, addMenuIdList);
        }

        //9.查询租户菜单ID
        List<TenantMenuPO> tenantMenuList = this.query().select("id", "menu_id").eq("tenant_id", tenantId).list();

        //10.获取添加的ID
        List<Long> addIdList = tenantMenuList.stream().map(TenantMenuPO::getId).distinct().collect(Collectors.toList());

        //11.给管理员添加 sys_role_menu
        iRoleMenuService.addByTenantIdMenuId(tenantId, addIdList);

        //12.设置资源 sys_menu_resource
        iMenuResourceService.setByTenantIdMenuId(tenantId, tenantMenuList, tenantMenuResourceDTO.getTenantMenuResourceList());

        return "分配成功！";
    }

    @Transactional
    public void addByMenuIdList(Long tenantId, List<Long> menuIdList) {
        //1.当前用户
        LoginUserDetail currentUser = JwtUtil.getCurrentUser();

        //2.转换成实体类
        List<TenantMenuPO> tenantMenuList = menuIdList.stream()
                .map(item -> new TenantMenuPO()
                        .setTenantId(tenantId)
                        .setMenuId(item)
                        .setParentId(ApiConst.SUPER_PARENT_ID)
                        .setCreateBy(currentUser.getName())
                        .setStatus(StatusEnum.ENABLE.getStatus())
                        .setSeq(0))
                .collect(Collectors.toList());

        //3.执行保存
        this.saveBatch(tenantMenuList);

        //4.修改 tree_link_id,并修改
        List<TenantMenuPO> updateTreeLinkId = tenantMenuList.stream().map(item -> new TenantMenuPO()
                        .setId(item.getId())
                        .setTreeLinkId(String.format("%s,%s", ApiConst.SUPER_PARENT_ID, item.getId())))
                .collect(Collectors.toList());
        this.updateBatchById(updateTreeLinkId);
    }

    @Override
    public List<TenantMenuResourceVO> getMenuResourceByTenantId(Long tenantId) {
        //1.获取所有的资源路径
        Map<String, List<String>> allPath = applicationStartEventListener.getNotSecurityPathToMap();

        //2.封装请求参数
        Map<String, Object> param = ApiConst.enableStatusAndUnableDelete();
        param.put("tenantId", tenantId);
        param.put("pathList", allPath.keySet());

        //3.查询所有菜单
        List<TenantMenuResourceVO> result = this.baseMapper.getMenuIdByTenantId(param);

        //4.查询所有资源（id,name,path）
        List<ResourcePO> allResourceList = iResourceService.getAllIdNamePath();

        //5.所有的租户菜单ID
        List<Long> tenantMenuIdList = result.stream().filter(item -> Objects.nonNull(item.getMenuId())).map(TenantMenuResourceVO::getId).distinct().collect(Collectors.toList());

        //6.查询已存在的资源
        Map<Long, List<Long>> menuResourceMap = iMenuResourceService.getByGroupTenantMenuId(tenantId, tenantMenuIdList);

        //7.封装数据并返回
        return result.stream()
                .map(item -> item
                        .setSelectResourceList(menuResourceMap.get(item.getId()))
                        .setAllResourceList(allResourceList.stream()
                                .filter(resource -> allPath.get(item.getPath()).contains(resource.getPath()))
                                .collect(Collectors.toMap(ResourcePO::getId, ResourcePO::getName))))
                .collect(Collectors.toList());
    }
}